package com.autohelper.app.tcp.client;


import android.util.Log;


import com.autohelper.app.tcp.cmd.CmdEnum;
import com.autohelper.app.tcp.model.Message;
import com.autohelper.app.tcp.protocol.MessageDecoder;
import com.autohelper.app.tcp.protocol.MessageEncoder;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.GlobalEventExecutor;

public class NettyClient {
    private static final String TAG = "NettyClient";
    private static final int RECONNECT_DELAY = 5; // 重连延迟（秒）
    private static final int HEART_BEAT_INTERVAL = 30; // 心跳间隔（秒）

    private String host;
    private int port;
    private boolean isRunning = false;
    private Bootstrap bootstrap;
    private EventLoopGroup group;
    private Channel channel;
    private final String deviceNo;

    public NettyClient(String host, int port, String deviceNo) {
        this.host = host;
        this.port = port;
        this.deviceNo = deviceNo;
        this.init();
    }

    private void init() {
        group = new NioEventLoopGroup();
        bootstrap = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new IdleStateHandler(0, HEART_BEAT_INTERVAL, 0));
                        ch.pipeline().addLast(new MessageDecoder());
                        ch.pipeline().addLast(new MessageEncoder());
                        ch.pipeline().addLast(new ClientHandler());
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                                super.channelInactive(ctx);
                                GlobalEventExecutor.INSTANCE.schedule(NettyClient.this::start, 10, TimeUnit.SECONDS);
                            }
                        });
                    }
                });
    }


    public void start() {
        isRunning = true;
        connect();
    }

    private void connect() {
        if (!isRunning) {
            return;
        }

        bootstrap.connect(host, port).addListener((ChannelFutureListener) future -> {
            if (future.isSuccess()) {
                channel = future.channel();
                Message message = new Message();
                message.setCommand(CmdEnum.DEVICE_NO.code);
                message.setVersion((short) 0);
                message.setReqId(0L);
                message.setContent(this.deviceNo.getBytes(StandardCharsets.UTF_8));
                message.setLength(message.getContent().length);
                channel.writeAndFlush(message);
                Log.i(TAG, "连接服务器成功");
            } else {
                Log.e(TAG, "连接服务器失败:" + future.cause().getMessage());
                Log.e(TAG, RECONNECT_DELAY + "秒后重试");
                future.channel().eventLoop().schedule(this::connect, RECONNECT_DELAY, TimeUnit.SECONDS);
            }
        });
    }

    public void stop() {
        isRunning = false;
        if (channel != null) {
            channel.close();
            channel = null;
        }
        if (group != null) {
            group.shutdownGracefully();
        }
    }

    public boolean isConnected() {
        return channel != null && channel.isActive();
    }


    public void sendMessage(String message) {
        if (isConnected()) {
            channel.writeAndFlush(message + "\n");
        } else {
            Log.w(TAG, "连接断开，无法发送消息");
        }
    }

    public Channel getChannel() {
        return channel;
    }

    public static void main(String[] args) throws Exception {
        new NettyClient("127.0.0.1", 8080, "1000").start();
    }
}